www.gusucode.com > vc++ 远程控制示例源程序-源码程序 > vc++ 远程控制示例源程序-源码程序\code\PeerYouC\SearchHostDlg.cpp
// SearchHostDlg.cpp : implementation file // Download by http://www.NewXing.com #include "stdafx.h" #include "PeerYouC.h" #include "SearchHostDlg.h" #include "Peersocket.h" #include "command.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif HANDLE hThread; HANDLE hThreadExit; PARAM paa; ///////////////////////////////////////////////////////////////////////////// // CSearchHostDlg dialog CSearchHostDlg::CSearchHostDlg(CWnd* pParent /*=NULL*/) : CDialog(CSearchHostDlg::IDD, pParent) { //{{AFX_DATA_INIT(CSearchHostDlg) //}}AFX_DATA_INIT bExit=false; bRealExit=false; } void CSearchHostDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CSearchHostDlg) DDX_Control(pDX, IDC_PROGRESS, m_Process); DDX_Control(pDX, IDC_LIST_HOST, m_listHosts); DDX_Control(pDX, IDC_IPADDRESS_SECOND, m_HostAddrSecond); DDX_Control(pDX, IDC_IPADDRESS_FIRST, m_HostAddrFirst); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CSearchHostDlg, CDialog) //{{AFX_MSG_MAP(CSearchHostDlg) ON_BN_CLICKED(IDC_EXIT, OnExit) ON_BN_CLICKED(IDC_SEARCH, OnSearch) ON_WM_CLOSE() ON_BN_CLICKED(IDC_STOP, OnStop) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CSearchHostDlg message handlers void CSearchHostDlg::OnExit() { // TODO: Add your control notification handler code here if(bRealExit) SendMessage(WM_CLOSE); else MessageBox("需要先中止搜索"); } BOOL CSearchHostDlg::OnInitDialog() { CDialog::OnInitDialog(); // TODO: Add extra initialization here bExit=false; CRect rtClient; m_listHosts.GetClientRect(rtClient); LVCOLUMN colinfo; memset(&colinfo,0,sizeof(colinfo)); colinfo.mask=LVCF_WIDTH|LVCF_FMT|LVCF_TEXT; colinfo.fmt=LVCFMT_CENTER; colinfo.cchTextMax=255; colinfo.cx=rtClient.Width()-40; colinfo.pszText="服务器地址"; m_listHosts.InsertColumn(0,&colinfo); colinfo.cx=40; colinfo.pszText="状态"; m_listHosts.InsertColumn(1,&colinfo); if(!CreateEvent(NULL,true,false,NULL)) return false; ResetEvent(hThreadExit); return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } void CSearchHostDlg::OnSearch() { // TODO: Add your control notification handler code here CMainFrame* wMainFrame=(CMainFrame*)AfxGetApp()->GetMainWnd(); CTreeCtrl& tree=wMainFrame->m_pTreeHost->GetTreeCtrl(); if(!tree.DeleteAllItems()) ASSERT(false); if(!m_listHosts.DeleteAllItems()) ASSERT(false); CButton* button=(CButton*)GetDlgItem(IDC_SEARCH); if(button) button->EnableWindow(false); CStatic* sta=(CStatic*)GetDlgItem(IDC_MESSAGE); if(sta) sta->ShowWindow(SW_HIDE); ///////////////////////// CString addrstart,addrend; m_HostAddrFirst.GetWindowText(addrstart); m_HostAddrSecond.GetWindowText(addrend); if(addrstart>addrend) { MessageBox("第二个地址应大于第一个地址"); return ; } ULONG lStart=ntohl(inet_addr(addrstart)); ULONG lEnd=ntohl(inet_addr(addrend)); ULONG lSub=lEnd-lStart+1; //一共有多少个地址 m_Process.SetRange32(0,lSub); m_Process.ShowWindow(SW_SHOW); UINT ThreadID; HTREEITEM item=tree.InsertItem( "PeerYou服务器",0,0); paa.dlg=(void*)this; paa.count=lSub; paa.now=lStart; if((hThread=BeginThread(SearchFun,&paa,&ThreadID))<=0) { MessageBox("创建搜索线程失败"); if(!tree.DeleteAllItems()) ASSERT(false); return; } tree.Expand(item,TVE_EXPAND); } UINT WINAPI SearchFun(PVOID param) { PARAM npa; memcpy(&npa,param,sizeof(PARAM)); WSAEVENT event=WSACreateEvent(); DWORD add; SOCKET sock; DWORD ret; int nhost=0; int index; CSearchHostDlg* dlg=(CSearchHostDlg*)npa.dlg; CMainFrame *mframe=(CMainFrame*)AfxGetApp()->GetMainWnd(); CTreeCtrl& tree=mframe->m_pTreeHost->GetTreeCtrl(); HTREEITEM item=tree.GetRootItem(); HTREEITEM item2; SYSTEMINIT si; COMMAND com; char address[16]; for(int i=0;i<npa.count;i++) { if(dlg->bExit) { dlg->bExit=false; closesocket(sock); WSACloseEvent(event); SetEvent(hThreadExit); return 0; } PeerCreateSocket(&sock,PEER_STREAM); add=npa.now+i; add=htonl(add); in_addr ina; memset(&ina,0,sizeof(ina)); ina.S_un.S_addr=add; strcpy(address,inet_ntoa(ina)); int TimeOut=6000; //设置发送超时6秒 if(::setsockopt(sock,SOL_SOCKET,SO_SNDTIMEO,(char *)&TimeOut,sizeof(TimeOut))==SOCKET_ERROR) { ::closesocket (sock); continue; } TimeOut=6000;//设置接收超时6秒 if(::setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,(char *)&TimeOut,sizeof(TimeOut))==SOCKET_ERROR) { ::closesocket (sock); continue; } //设置非阻塞方式连接 unsigned long ul = 1; ret = ioctlsocket(sock, FIONBIO, (unsigned long*)&ul); if(ret==SOCKET_ERROR) { ::closesocket (sock); continue; } PeerConnectSocket(sock,address,7788); //select 模型,即设置超时 struct timeval timeout ; fd_set r; FD_ZERO(&r); FD_SET(sock, &r); timeout.tv_sec = 2; //连接超时15秒 timeout.tv_usec =0; ret = select(0, 0, &r, 0, &timeout); if ( ret >0 ) { //一般非锁定模式套接比较难控制,可以根据实际情况考虑 再设回阻塞模式 unsigned long ul1= 0 ; ret = ioctlsocket(sock, FIONBIO, (unsigned long*)&ul1); if(ret==SOCKET_ERROR){ ::closesocket (sock); continue; } index=dlg->m_listHosts.InsertItem(dlg->m_listHosts.GetItemCount(),address); dlg->m_listHosts.SetItemText(index,1,"在线"); item2=tree.InsertItem(address,1,1,item); memset(&com,0,sizeof(com)); com.CommandID=PEER_SYSTEM_INIT; com.DataSize=0; if(PeerSendDataS(sock,(char*)&com,sizeof(com),&ret,event)&&ret==sizeof(com)) { if(PeerRecvDataS(sock,(char*)&si,sizeof(si),&ret,event)&&ret==sizeof(si)) { tree.InsertItem(si.computer,2,2,item2); tree.InsertItem(si.user,3,3,item2); tree.InsertItem(si.os,4,4,item2); tree.InsertItem(si.processor,5,5,item2); tree.InsertItem(si.mem,6,6,item2); tree.InsertItem(si.disk,7,7,item2); } } tree.RedrawWindow(); nhost++; } else { index=dlg->m_listHosts.InsertItem(dlg->m_listHosts.GetItemCount(),address); dlg->m_listHosts.SetItemText(index,1,"未通"); } dlg->m_Process.SetPos(i+1); closesocket(sock); } WSACloseEvent(event); dlg->m_Process.ShowWindow(SW_HIDE); CButton* button=(CButton*)dlg->GetDlgItem(IDC_SEARCH); if(button) button->EnableWindow(true); CStatic* sta=(CStatic*)dlg->GetDlgItem(IDC_MESSAGE); if(sta) { sta->ShowWindow(SW_SHOW); char msg[100]; sprintf(msg,"查找已经完成,%d个主机在线!",nhost); sta->SetWindowText(msg); } if(nhost==0) tree.DeleteAllItems(); dlg->bExit=false; return 0; } void CSearchHostDlg::OnClose() { // TODO: Add your message handler code here and/or call default CDialog::OnClose(); } void CSearchHostDlg::OnStop() { // TODO: Add your control notification handler code here UpdateData(); bExit=true; bRealExit=true; DWORD n = WaitForSingleObject(hThreadExit,60000); Sleep(500); if(n==WAIT_TIMEOUT) { TerminateThread(hThread,0); } CloseHandle(hThreadExit); CloseHandle(hThread); CStatic* sta=(CStatic*)GetDlgItem(IDC_MESSAGE); m_Process.ShowWindow(SW_HIDE); CButton* button=(CButton*)GetDlgItem(IDC_SEARCH); button->EnableWindow(); if(sta) { sta->ShowWindow(SW_SHOW); sta->SetWindowText("中止搜索主机!"); } }